﻿using System;

using System.IO;
using System.Xml;
using Microsoft.WindowsAzure.ServiceRuntime;
using NougakudoCompanion.Commons;

namespace NougakudoCompanion.Utils
{
    public class NougakudoEnvironment
    {
        string WORKING_FOLDER = null;
        string RUNTIME = null;
        string APPLICATION = null;
        string DOWNLOAD = null;
        string ROLE_ROOT = null;
        string TEMP = null;         // Add temporary folder variable.

        static int interval = 0;
        static string runtimeFolder = "";

        NougakudoEnvironment()
        {
            WORKING_FOLDER = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_WORKING_FOLDER);
            //RUNTIME = Path.Combine(RoleEnvironment.GetLocalResource(Constants.RESOURCE_RUNTIME).RootPath, WORKING_FOLDER);
            //APPLICATION = Path.Combine(RoleEnvironment.GetLocalResource(Constants.RESOURCE_APPLICATION).RootPath, WORKING_FOLDER);
            //DOWNLOAD = Path.Combine(RoleEnvironment.GetLocalResource(Constants.RESOURCE_DOWNLOAD).RootPath, WORKING_FOLDER);
            var root = ShortcutPathUtility.GetShortcutRoot();
            RUNTIME = Path.Combine(root, Constants.RESOURCE_RUNTIME, WORKING_FOLDER);
            APPLICATION = Path.Combine(root, Constants.RESOURCE_APPLICATION, WORKING_FOLDER);
            DOWNLOAD = Path.Combine(root, Constants.RESOURCE_DOWNLOAD, WORKING_FOLDER);
            ROLE_ROOT = System.Environment.ExpandEnvironmentVariables(@"%RoleRoot%\approot");
            TEMP = Path.Combine(root, Constants.RESOURCE_TEMP, WORKING_FOLDER);  // Add temp folder
        }

        public static int Interval { get { return interval; } }
        public static string RuntimeFolder { get { return runtimeFolder; } }

        /// <summary>
        /// Create azure.xml as NougakuDo environment of Windows Azure.
        /// </summary>
        /// <returns></returns>
        public static bool Start()
        {
#if DEBUG
            Logging.Write("Create azure.xml");
#endif
            var nougakudo = new NougakudoEnvironment();
            var ret = nougakudo.CreateAzureEnvironment();
            Logging.Write("The result of created azure,xml = " + ret.ToString());
            return ret;
        }

        bool CreateAzureEnvironment()
        {
            try
            {
                var doc = new XmlDocument();
                var root = doc.CreateElement("azure");
                var runtime = CreateRuntimeElement(doc);
                var blob = CreateBlobElement(doc);
                var dec = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");

                root.AppendChild(runtime);
                root.AppendChild(blob);
                doc.AppendChild(root);
                doc.InsertBefore(dec, root);

                var config = Path.Combine(RUNTIME, Constants.AZURE_CONFIGURATION);
                doc.Save(config);
                return true;
            }
            catch (Exception e)
            {
                Logging.Write("config error = " + e.Message);
                return false;
            }
        }

        XmlElement CreateRuntimeElement(XmlDocument doc)
        {
            var runtime = doc.CreateElement("runtime");
            var runtimeFolder = doc.CreateElement("runtimefolder");
            runtimeFolder.InnerText = RUNTIME;
            runtime.AppendChild(runtimeFolder);
            var applicationFolder = doc.CreateElement("applicationfolder");
            applicationFolder.InnerText = APPLICATION;
            runtime.AppendChild(applicationFolder);
            var downlaodFolder = doc.CreateElement("downloadfolder");
            downlaodFolder.InnerText = DOWNLOAD;
            runtime.AppendChild(downlaodFolder);
            var roleRoot = doc.CreateElement("roleroot");
            roleRoot.InnerText = ROLE_ROOT;
            runtime.AppendChild(roleRoot);
            var roleInstance = doc.CreateElement("roleinstance");
            roleInstance.InnerText = RoleEnvironment.CurrentRoleInstance.Id;

            // Add temp folder
            var temp = doc.CreateElement("tempfolder");
            temp.InnerText = TEMP;
            runtime.AppendChild(temp);

            runtime.AppendChild(roleInstance);
            var deploymentId = doc.CreateElement("deploymentid");
            deploymentId.InnerText = RoleEnvironment.DeploymentId;
            runtime.AppendChild(deploymentId);
            var hostName = doc.CreateElement("hostname");
            hostName.InnerText = System.Net.Dns.GetHostName();
            runtime.AppendChild(hostName);
            var machineName = doc.CreateElement("machinername");
            machineName.InnerText = System.Environment.MachineName;
            runtime.AppendChild(machineName);

            // // Add for NougakuDo 1.1.0 above.
            var virtualHost = doc.CreateElement("virtualhost");
            virtualHost.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_VIRTUALHOST);
            runtime.AppendChild(virtualHost);

            var nougakudo = doc.CreateElement("name");
            nougakudo.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_NAME);
            runtime.AppendChild(nougakudo);
            var interval = doc.CreateElement("interval");
            interval.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_INTERVAL);
            runtime.AppendChild(interval);
            var developmentfabroc = doc.CreateElement("usedevelopmentfabric");
            //developmentfabroc.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_DEVLOPMENTFABRIC);
            developmentfabroc.InnerText = RoleEnvironment.IsEmulated.ToString().ToLower();  // Add for Azure SDK 1.5.
            runtime.AppendChild(developmentfabroc);

            NougakudoEnvironment.interval = int.Parse(RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_INTERVAL));
            NougakudoEnvironment.runtimeFolder = RUNTIME;

            return runtime;
        }

        XmlElement CreateBlobElement(XmlDocument doc)
        {
            var blob = doc.CreateElement("blob");
            var account = doc.CreateElement("account");
            account.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_ACCOUNT);
            blob.AppendChild(account);
            var sharedKey = doc.CreateElement("sharedkey");
            sharedKey.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_SHAREDKEY);
            blob.AppendChild(sharedKey);
            var container = doc.CreateElement("container");
            container.InnerText = RoleEnvironment.GetConfigurationSettingValue(Constants.AZURE_CONFIG_CONTAINER);
            blob.AppendChild(container);

            // output environment variables for test purpose.
#if DEBUG
            var test = doc.CreateElement("variables");
            string d = "";
            foreach (System.Collections.DictionaryEntry i in System.Environment.GetEnvironmentVariables())
            {
                d += "%" + i.Key.ToString() + "%=" + i.Value.ToString() + "%;%";
            }
            test.InnerText = d;
            blob.AppendChild(test);
#endif

            return blob;
        }

    }
}